package com.element.oauth2.server.authorization;

import com.element.oauth2.constant.SecurityParams;
import com.element.oauth2.server.handler.AuthErrorAuthenticationFailureHandler;
import org.springframework.context.annotation.Bean;
import org.springframework.http.HttpMethod;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.web.SecurityFilterChain;

/**
 * 服务安全相关配置
 */
@EnableWebSecurity
public class WebSecurityConfiguration {

    private final static String AUTHORIZE_TOKEN_URL = SecurityParams.AUTHORIZATION_ENDPOINT_URL;
    private final static String OAUTH_TOKEN_URL = SecurityParams.TOKEN_ENDPOINT_URL;

    public final static String LOGIN_PAGE = SecurityParams.LOGIN_PAGE;
    private final static String LOGIN_PROCESS_URL = "/login/submit";

    private final static String ERROR_URL = "/error";

    private final static String LOGIN_PAGE_CSS = "/css/signin.css";
    private final static String BOOTSTRAP_CSS = "/css/bootstrap.min.css";

    /**
     * spring security 默认的安全策略
     *
     * @param http security注入点
     * @return SecurityFilterChain
     */
    @Bean
    SecurityFilterChain defaultSecurityFilterChain(HttpSecurity http) throws Exception {
        http.csrf().disable().headers().frameOptions().disable();

        // 必须配置，不然OAuth2的http配置不生效
        http.requestMatchers()
                .antMatchers(LOGIN_PAGE)
                .antMatchers(LOGIN_PROCESS_URL)
                .antMatchers(AUTHORIZE_TOKEN_URL)
                .antMatchers(OAUTH_TOKEN_URL)
                .antMatchers(ERROR_URL);

        //  开放自定义的部分端点
        http.authorizeHttpRequests()
                .antMatchers(HttpMethod.GET, LOGIN_PAGE, LOGIN_PAGE_CSS, BOOTSTRAP_CSS, OAUTH_TOKEN_URL)
                .permitAll()
                .anyRequest()
                .authenticated(); // 其他页面都授权;

        http.formLogin()
                .loginPage(LOGIN_PAGE)
                .loginProcessingUrl(LOGIN_PROCESS_URL)
                // .successHandler(new TokenAuthenticationSuccessHandler(1))
                .failureHandler(new AuthErrorAuthenticationFailureHandler());

        http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.NEVER);
        // 可以设置踢出用户后续操作
        http.sessionManagement().maximumSessions(1).maxSessionsPreventsLogin(false);
        http.sessionManagement().sessionFixation().none();

        return http.build();
    }
}